﻿/**
 *	ui/html_bridge.cpp
 *
 *	(C) 2014 Yuanjj
 *
 *	create a bridge between "c++" and "js"
 *
 * 	history:
 * 		2014-06-25		create the file
 */

#include "html_bridge.h"
#include "errorcode.h"
#include "routine/global.h"
#include "routine/tunnel/tunnel.h"
#include "routine/protocal/protocal.h"
#include "routine/protocal/db_protocal.h"
#include <QFileDialog>
#include <QGraphicsWebView>
#include <QWebFrame>
#include <QMessageBox>

// call js function
#define		JS_INTERFACE	webView()->page()->mainFrame()->evaluateJavaScript

cls_bridge::cls_bridge( MainWindow* parent ) : MainWindow( parent )
{
    connect( webView()->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
             this, SLOT(populateJavaScriptWindowObject()) );
}

cls_bridge::~cls_bridge()
{
}

/**
 *	initialize the bridge object
 *
 * 	return
 * 		==	PEM_OK		successful
 * 		!=	PEM_OK		errorcode
 */
pem_error_t cls_bridge::instance()
{
    LoadFile( "./html/pem_main.html" );
    init_window_size( MIN_WIDTH, MIN_HEIGHT );

    return	PEM_OK;
}

/**
 *	init the window size
 *
 * 	@width			[in] the window width
 * 	@height			[in] the window height
 */
pem_void_t cls_bridge::init_window_size( pem_s32_t width, pem_s32_t height )
{
    setMinimumWidth( width );
    setMinimumHeight( height );
}

/**
 *	add a qt object into js with another namespace name
 *
 *	@name		[in] the object name in js
 *	@obj		[in] the qt object connect with the object in js
 */
pem_void_t cls_bridge::set_javascript_object( QString name, QObject *obj )
{
    webView()->page()->mainFrame()->addToJavaScriptWindowObject( name, obj );
}

/**
 *	resize event callback
 *
 *	@event		[in] the event object pointer
 */
pem_void_t cls_bridge::resizeEvent( QResizeEvent *event )
{
    QString			js_fun;
    const QSize& 	size = event->size();

    webView()->resize( size );
    js_fun.sprintf( "if_resize(%d, %d);", size.width(), size.height() );

    call_js_routine( js_fun );
}

/**
 *	when javascript window object has been created, add the window's object to js
 */
void cls_bridge::populateJavaScriptWindowObject()
{
    set_javascript_object( "qt_html", this );
}

/**
 *	call javascript routine
 *
 *	@js_fun			[in] javascript function with param
 */
pem_void_t cls_bridge::call_js_routine( QString& js_fun )
{
    JS_INTERFACE( js_fun );
}

/**************************************************************************************
 * js call back
 **************************************************************************************/
/**
 *	user login
 *
 * 	@account		[in] user account
 * 	@passwd			[in] pass word
 */
void cls_bridge::user_login( QString account, QString passwd )
{
    pem_s8_t			buf[8192];
    head_in&			head		= *(head_in*)buf;
    db_user_login*		dblogin		= (db_user_login*)(&head + 1);
    QByteArray			ba;

    FILL_HEAD( head, MAIN_DB, DB_USER_LOGIN, EN_NONE, sizeof(db_user_login) );
    ba = account.toLatin1();
    strncpy( dblogin->account, ba.data(), sizeof(dblogin->account) );
    ba = passwd.toLatin1();
    strncpy( dblogin->passwd, ba.data(), sizeof(dblogin->passwd) );

    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**********************************************************
 *	host data
 **********************************************************/
/**
 *	load host
 */
void cls_bridge::load_host()
{
    pem_s8_t		buf[8192];
    head_in&		head	= *(head_in*)buf;

    FILL_HEAD( head, MAIN_DB, DB_HOST, EN_NONE, sizeof(db_host) );
    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**********************************************************
 *	tunnel data
 **********************************************************/
/**
 *	load tunnel type
 */
void cls_bridge::load_tunnel_type()
{
    pem_s8_t		buf[8192];
    head_in&		head	= *(head_in*)buf;

    FILL_HEAD( head, MAIN_DB, DB_TUNNEL_TYPE, EN_NONE, sizeof(db_tunnel_type) );
    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**
 *	load tunnel
 */
void cls_bridge::load_tunnel()
{
    pem_s8_t		buf[8192];
    head_in&		head	= *(head_in*)buf;

    FILL_HEAD( head, MAIN_DB, DB_TUNNEL, EN_NONE, sizeof(db_tunnel) );
    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**
 *	update tunnel
 *
 * 	@name			[in] the tunnel name
 * 	@type			[in] the tunnel type
 * 	@number			[in] the tunnel number
 * 	@host			[in] the host number
 * 	@remark			[in] the tunnel remark
 * 	@used			[in] the tunnel used flag
 */
void cls_bridge::update_tunnel( QString name, QString type, QString number, QString host, QString remark, QString used )
{
    pem_s8_t			buf[8192];
    head_in&			head	= *(head_in*)buf;
    db_tunnel_update&	tunnel	= *(db_tunnel_update*)(&head + 1);
    QByteArray			ba;

    ba = name.toUtf8();
    strncpy( tunnel.name, ba.data(), sizeof(tunnel.name) );
    ba = type.toUtf8();
    strncpy( tunnel.type, ba.data(), sizeof(tunnel.type) );
    ba = number.toUtf8();
    strncpy( tunnel.number, ba.data(), sizeof(tunnel.number) );
    ba = host.toUtf8();
    strncpy( tunnel.host, ba.data(), sizeof(tunnel.host) );
    ba = remark.toUtf8();
    strncpy( tunnel.remark, ba.data(), sizeof(tunnel.remark) );
    ba = remark.toUtf8();
    tunnel.used = ba.toInt();

    FILL_HEAD( head, MAIN_DB, DB_TUNNEL_UPDATE, EN_NONE, sizeof(db_tunnel_update) );
    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**
 *	delete tunnel
 *
 * 	@number			[in] the tunnel number ( key for tab_tunnel )
 */
void cls_bridge::delete_tunnel( QString number )
{
    pem_s8_t			buf[8192];
    head_in&			head	= *(head_in*)buf;
    db_tunnel_delete&	tunnel	= *(db_tunnel_delete*)(&head + 1);
    QByteArray			ba;

    ba = number.toUtf8();
    strncpy( tunnel.number, ba.data(), sizeof(tunnel.number) );

    FILL_HEAD( head, MAIN_DB, DB_TUNNEL_DELETE, EN_NONE, sizeof(db_tunnel_delete) );
    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**********************************************************
 *	device data
 **********************************************************/
/**
 *	load device type
 */
void cls_bridge::load_device_type()
{
    pem_s8_t		buf[8192];
    head_in&		head	= *(head_in*)buf;

    FILL_HEAD( head, MAIN_DB, DB_DEV_TYPE, EN_NONE, sizeof(db_dev_type) );
    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**
 *	load protocal
 */
void cls_bridge::load_protocal()
{
    pem_s8_t		buf[8192];
    head_in&		head	= *(head_in*)buf;

    FILL_HEAD( head, MAIN_DB, DB_PROTOCAL, EN_NONE, sizeof(db_protocal) );
    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**
 *	load device
 */
void cls_bridge::load_device()
{
    pem_s8_t		buf[8192];
    head_in&		head	= *(head_in*)buf;

    FILL_HEAD( head, MAIN_DB, DB_DEVICE, EN_NONE, sizeof(db_device) );
    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**
 *	update device
 */
void cls_bridge::update_device( QString param )
/*
                    QString dev_id, QString dev_type, QString dev_name, QString dev_pos,
                    QString machine, QString tunnel_num, QString pto_name, QString pto_file,
                    QString host, QString value, QString x, QString y, QString setup )
                    */
{
    pem_s8_t			buf[8192];
    head_in&			head	= *(head_in*)buf;
    db_device_update&	device	= *(db_device_update*)(&head + 1);
    QByteArray			ba		= param.toUtf8();

    sscanf( ba.data(), "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%d,%d,%d",
                        device.dev_id, device.dev_type, device.dev_name, device.dev_pos,
                        device.machine, device.tunnel_num, device.pto_name, device.pto_file,
                        device.host, device.value, &device.x, &device.y, &device.setup );

    /*
    QMessageBox box(this);

    box.setText( ba.data() );
    box.exec();
    */

    /*
    ba = dev_id.toLatin1();
    strncpy( device.dev_id, ba.data(), sizeof(device.dev_id) );
    ba = dev_type.toLatin1();
    strncpy( device.dev_type, ba.data(), sizeof(device.dev_type) );
    ba = dev_name.toLatin1();
    strncpy( device.dev_name, ba.data(), sizeof(device.dev_name) );
    ba = dev_pos.toLatin1();
    strncpy( device.dev_pos, ba.data(), sizeof(device.dev_pos) );
    ba = machine.toLatin1();
    strncpy( device.machine, ba.data(), sizeof(device.machine) );
    ba = tunnel_num.toLatin1();
    strncpy( device.tunnel_num, ba.data(), sizeof(device.tunnel_num) );
    ba = pto_name.toLatin1();
    strncpy( device.pto_name, ba.data(), sizeof(device.pto_name) );
    ba = pto_file.toLatin1();
    strncpy( device.pto_file, ba.data(), sizeof(device.pto_file) );
    ba = host.toLatin1();
    strncpy( device.host, ba.data(), sizeof(device.host) );
    ba = value.toLatin1();
    strncpy( device.value, ba.data(), sizeof(device.value) );
    ba = x.toLatin1();
    device.x		= ba.toInt();
    ba = y.toLatin1();
    device.y		= ba.toInt();
    ba = setup.toLatin1();
    device.setup	= ba.toInt();
    */

    FILL_HEAD( head, MAIN_DB, DB_DEVICE_UPDATE, EN_NONE, sizeof(db_device_update) );
    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**********************************************************
 *	alarm data
 **********************************************************/
/**
 *	load alarm
 */
void cls_bridge::load_alarm()
{
    pem_s8_t		buf[8192];
    head_in&		head	= *(head_in*)buf;

    FILL_HEAD( head, MAIN_DB, DB_ALARM, EN_NONE, sizeof(db_alarm) );
    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**********************************************************
 *	event data
 **********************************************************/
/**
 *	load event type
 */
void cls_bridge::load_event_type()
{
    pem_s8_t		buf[8192];
    head_in&		head	= *(head_in*)buf;

    FILL_HEAD( head, MAIN_DB, DB_EVENT_TYPE, EN_NONE, sizeof(db_event_type) );
    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**
 *	load event
 */
void cls_bridge::load_event()
{
    pem_s8_t		buf[8192];
    head_in&		head	= *(head_in*)buf;

    FILL_HEAD( head, MAIN_DB, DB_EVENT, EN_NONE, sizeof(db_event) );
    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**********************************************************
 *	scene data
 **********************************************************/
/**
 *	load scene
 */
void cls_bridge::load_scene()
{
    pem_s8_t		buf[8192];
    head_in&		head	= *(head_in*)buf;

    FILL_HEAD( head, MAIN_DB, DB_SCENE, EN_NONE, sizeof(db_scene) );
    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**
 *	save scene
 *
 * 	@scene			[in] the scene file
 */
void cls_bridge::save_scene( QString scene, QString receipt )
{
    pem_s8_t		buf[8192];
    head_in&		head	= *(head_in*)buf;
    db_scene_save*	save	= (db_scene_save*)(&head + 1);
    QByteArray		ba;

    FILL_HEAD( head, MAIN_DB, DB_SCENE_SAVE, EN_SCENE_SAVE, sizeof(db_scene_save) );

    scene.replace( "\\", "/" );
    ba = scene.toLatin1();
    strncpy( save->img, ba.data(), sizeof(save->img) );
    save->receipt 	= receipt.toInt();

    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**
 *	load frame
 */
void cls_bridge::load_frame()
{
    pem_s8_t		buf[8192];
    head_in&		head	= *(head_in*)buf;

    FILL_HEAD( head, MAIN_DB, DB_FRAME, EN_NONE, sizeof(db_frame) );
    g_tunnel.putdata( CL_DB, buf, sizeof(head_in) + head.size );
}

/**********************************************************
 *	sync call
 **********************************************************/
/**
 *	open file select dialog
 *
 * 	@cmp_id			[in] the Extjs component id
 */
void cls_bridge::file_select( QString cmp_id )
{
    QFileDialog	fileDialog(this);

    fileDialog.setWindowTitle(tr("Open Image"));
    fileDialog.setDirectory(".");
    if(fileDialog.exec() == QDialog::Accepted)
    {
        QString js_fun;
        QString path 	= fileDialog.selectedFiles()[0];

        path.replace( "\\", "/" );
        js_fun = "callback_file_select(\"" + cmp_id + "\", \"" + path + "\");";
        call_js_routine( js_fun );
    }
}

/******************************************
 * c++ call back
 ******************************************/
/**
 *	call js function
 *
 *	@js_fun			[in] javascript function with param
 */
void cls_bridge::on_call_js( QString js_fun )
{
    call_js_routine( js_fun );
}
